package com.chinalcoal.ai.utils.util;

import com.lowagie.text.*;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.*;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.web.multipart.MultipartFile;

import java.awt.Color;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * Word转PDF工具类（支持中文、图片和水印）
 * 使用 Apache POI 和 OpenPDF
 */
public class WordToPdf {

    public static void main(String[] args) {
        try {
            // 指定中文字体路径
            String fontPath = "C:/Windows/Fonts/simsun.ttc"; // Windows
            // String fontPath = "/System/Library/Fonts/PingFang.ttc"; // macOS
            String inputFilePath = "G:\\我的项目\\PDF转图片\\pdfToImage\\jbpm集成.docx";
            String outputFilePath = "G:\\我的项目\\PDF转图片\\pdfToImage\\jbpm集成.pdf";
            // 转换Word到PDF并添加水印
            WordToPdf.convertWithOrderPreserved(
                    new File(inputFilePath),
                    outputFilePath,
                    "", // 水印文字
                    fontPath
            );

            System.out.println("转换成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 转换Word文档为PDF并保持元素顺序
     *
     * @param wordFile      Word文件
     * @param outputPdfPath 输出PDF路径
     * @param watermarkText 水印文字
     * @param fontPath      中文字体文件路径
     * @throws IOException 文件操作异常
     */
    public static void convertWithOrderPreserved(File wordFile, String outputPdfPath,
                                                 String watermarkText, String fontPath) throws IOException {
        try (FileInputStream fis = new FileInputStream(wordFile);
             XWPFDocument document = new XWPFDocument(fis);
             FileOutputStream out = new FileOutputStream(outputPdfPath)) {

            // 创建PDF文档
            Document pdfDoc = new Document();
            PdfWriter writer = PdfWriter.getInstance(pdfDoc, out);

            // 设置水印
            if (watermarkText != null && !watermarkText.trim().isEmpty()) {
                writer.setPageEvent(new TextWatermark(watermarkText, fontPath));
            }

            pdfDoc.open();

            // 按顺序处理所有Body元素
            processBodyElementsInOrder(document, pdfDoc, fontPath);

            pdfDoc.close();
        } catch (DocumentException e) {
            throw new IOException("PDF文档操作失败: " + e.getMessage(), e);
        }
    }

    /**
     * 按顺序处理文档中的所有元素
     */
    private static void processBodyElementsInOrder(XWPFDocument document, Document pdfDoc, String fontPath)
            throws DocumentException, IOException {
        // 获取所有Body元素（按文档中的顺序）
        List<IBodyElement> bodyElements = document.getBodyElements();

        // 创建中文字体
        BaseFont baseFont = BaseFont.createFont(fontPath + ",0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font chineseFont = new Font(baseFont, 12);

        for (IBodyElement element : bodyElements) {
            if (element instanceof XWPFParagraph) {
                // 处理段落
                processParagraph((XWPFParagraph) element, pdfDoc, chineseFont);
            } else if (element instanceof XWPFTable) {
                // 处理表格
                processTable((XWPFTable) element, pdfDoc, chineseFont);
            }
            // 可以添加其他元素类型的处理，如页眉页脚等
        }
    }

    /**
     * 处理段落元素
     */
    private static void processParagraph(XWPFParagraph paragraph, Document pdfDoc, Font font)
            throws DocumentException {
        String text = paragraph.getText();
        if (text != null && !text.trim().isEmpty()) {
            pdfDoc.add(new Paragraph(text, font));
        }

        // 处理段落中的图片
        processPicturesInParagraph(paragraph, pdfDoc);
    }

    /**
     * 处理段落中的图片
     */
    private static void processPicturesInParagraph(XWPFParagraph paragraph, Document pdfDoc) {
        for (XWPFRun run : paragraph.getRuns()) {
            // 检查运行元素中的图片
            for (XWPFPicture picture : run.getEmbeddedPictures()) {
                try {
                    byte[] bytes = picture.getPictureData().getData();
                    Image image = Image.getInstance(bytes);
                    image.scaleToFit(500, 300); // 调整图片大小
                    pdfDoc.add(image);
                } catch (Exception e) {
                    System.err.println("图片处理失败: " + e.getMessage());
                }
            }
        }
    }

    /**
     * 处理表格元素
     */
    private static void processTable(XWPFTable table, Document pdfDoc, Font font)
            throws DocumentException {
        int numColumns = getTableColumnsCount(table);
        // 创建PDF表格
        PdfPTable pdfTable = new PdfPTable(numColumns);
        // 处理表格行
        for (XWPFTableRow row : table.getRows()) {
            for (XWPFTableCell cell : row.getTableCells()) {
                // 创建PDF单元格
                PdfPCell pdfCell = new PdfPCell();

                // 处理单元格内容（可能包含多个段落）
                for (XWPFParagraph para : cell.getParagraphs()) {
                    if (para.getText() != null && !para.getText().trim().isEmpty()) {
                        pdfCell.addElement(new Paragraph(para.getText(), font));
                    }
                }

                pdfTable.addCell(pdfCell);
            }
        }

        pdfDoc.add(pdfTable);
    }

    /**
     * 获取表格列数
     */
    private static int getTableColumnsCount(XWPFTable table) {
        if (table.getRows().isEmpty()) {
            return 0;
        }

        // 获取第一行的单元格数量作为列数
        XWPFTableRow firstRow = table.getRows().get(0);
        return firstRow.getTableCells().size();
    }

    /**
     * 文字水印事件处理类
     */
    public static class TextWatermark extends PdfPageEventHelper {
        private String watermarkText;
        private String fontPath;

        public TextWatermark(String watermarkText, String fontPath) {
            this.watermarkText = watermarkText;
            this.fontPath = fontPath;
        }

        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            try {
                PdfContentByte canvas = writer.getDirectContent();
                canvas.saveState();

                // 创建图形状态并设置透明度
                PdfGState gState = new PdfGState();
                gState.setFillOpacity(0.3f);
                canvas.setGState(gState);

                // 创建中文字体
                BaseFont baseFont = BaseFont.createFont(fontPath + ",0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                canvas.setFontAndSize(baseFont, 50);
                canvas.setColorFill(Color.LIGHT_GRAY);

                // 计算水印位置（在页面上重复显示）
                Rectangle pageSize = document.getPageSize();
                float pageWidth = pageSize.getWidth();
                float pageHeight = pageSize.getHeight();

                // 设置水印之间的间距
                float horizontalSpacing = 300f;
                float verticalSpacing = 200f;

                // 在页面上重复绘制水印 通过调整horizontalSpacing和verticalSpacing的值来控制水印的密度。
                for (float x = horizontalSpacing; x < pageWidth; x += horizontalSpacing) {
                    for (float y = verticalSpacing; y < pageHeight; y += verticalSpacing) {
                        // 添加水印文本
                        canvas.beginText();
                        canvas.showTextAligned(PdfContentByte.ALIGN_CENTER, watermarkText, x, y, 45);
                        canvas.endText();
                    }
                }

                canvas.restoreState();
            } catch (Exception e) {
                throw new RuntimeException("添加水印失败", e);
            }
        }
    }

    /**
     * 处理MultipartFile类型的Word文件转换
     */
    public static File convertMultipartFile(MultipartFile multipartFile, String outputPdfPath,
                                            String watermarkText, String fontPath) throws IOException {
        // 创建临时文件
        Path tempDir = Paths.get("temp");
        if (!Files.exists(tempDir)) {
            Files.createDirectories(tempDir);
        }

        File tempWordFile = tempDir.resolve(multipartFile.getOriginalFilename()).toFile();
        multipartFile.transferTo(tempWordFile);

        // 转换文件
        convertWithOrderPreserved(tempWordFile, outputPdfPath, watermarkText, fontPath);

        // 清理临时文件
        Files.deleteIfExists(tempWordFile.toPath());

        return new File(outputPdfPath);
    }
}